package com.org.msmvc.sys.controller;
import java.awt.Color;  
import java.awt.image.BufferedImage;  
import java.io.IOException;  
import java.text.SimpleDateFormat;
import java.util.Collection;

import javax.imageio.ImageIO;  
import javax.servlet.http.HttpServletRequest;  
import javax.servlet.http.HttpServletResponse;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;  
import org.apache.shiro.authc.ExcessiveAttemptsException;  
import org.apache.shiro.authc.IncorrectCredentialsException;  
import org.apache.shiro.authc.LockedAccountException;  
import org.apache.shiro.authc.UnknownAccountException;  
import org.apache.shiro.authc.UsernamePasswordToken;  
import org.apache.shiro.crypto.hash.Md5Hash;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.apache.shiro.session.Session;
import org.apache.shiro.session.mgt.eis.SessionDAO;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.subject.support.DefaultSubjectContext;
import org.apache.shiro.util.ByteSource;
import org.apache.shiro.web.util.WebUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.view.InternalResourceViewResolver;

import com.org.msmvc.sys.entity.SysUser;
import com.org.msmvc.sys.service.UserService;
import com.org.shiro.VerifyCodeUtil;
/**
 * 登录管理
 * @author  zsh
 */
@Controller  
@RequestMapping("logins") 
public class LoginController {
    private final static Logger logger = LoggerFactory.getLogger(LoginController.class);
	@Autowired
	private UserService userService;
	@Autowired
	private SessionDAO sessionDAO;
	/** 
     * 获取验证码图片和文本(验证码文本会保存在HttpSession中) 
     */  
    @RequestMapping("/getVerifyCodeImage")  
    public void getVerifyCodeImage(HttpServletRequest request, HttpServletResponse response) throws IOException {  
        //设置页面不缓存  
        response.setHeader("Pragma", "no-cache");  
        response.setHeader("Cache-Control", "no-cache");  
        response.setDateHeader("Expires", 0);  
        String verifyCode = VerifyCodeUtil.generateTextCode(VerifyCodeUtil.TYPE_NUM_ONLY, 4, null);  
        //将验证码放到HttpSession里面  
        request.getSession().setAttribute("verifyCode", verifyCode);
        logger.info("本次生成的验证码为[" + verifyCode + "],已存放到HttpSession中");
        //设置输出的内容的类型为JPEG图像  
        response.setContentType("image/jpeg");  
        BufferedImage bufferedImage = VerifyCodeUtil.generateImageCode(verifyCode, 90, 30, 3, true, Color.WHITE, Color.BLACK, null);  
        //写给浏览器  
        ImageIO.write(bufferedImage, "JPEG", response.getOutputStream());  
    }

       
    /** 
     * 用户登录 
     * @throws Exception 
     */  
    @RequestMapping(value="/login")
    public String  login(HttpServletRequest request, HttpServletResponse response) throws Exception{
        String resultPageURL = InternalResourceViewResolver.FORWARD_URL_PREFIX + "/";
        String message_login = null;
       // String exceptionClassName = (String)request.getAttribute("shiroLoginFailure");
       /* if(UnknownAccountException.class.getName().equals(exceptionClassName)) {
            message_login = "用户名/密码错误";
        } else if(IncorrectCredentialsException.class.getName().equals(exceptionClassName)) {
            message_login = "用户名/密码错误";
        } else if(exceptionClassName != null) {
            message_login = "其他错误：" + exceptionClassName;
        }*/

        String username = request.getParameter("username");  
        String password = request.getParameter("password");  

        SysUser user = userService.getByUserName(username);
        if(user==null){
        	request.setAttribute("message_login", "帐号不存在！！");  
        	 return resultPageURL; 
        }else{
        	if(user.getStatus().equals("0")){
        		request.setAttribute("message_login", "帐号被禁用！！");  
           	 return resultPageURL;
        	}
        }

        if(request.getParameter("forceLogout") != null) {
            message_login= "您已经被管理员强制退出，请重新登录";
        }
        UsernamePasswordToken token = new UsernamePasswordToken(username, password);
        token.setRememberMe(true);  
        //获取当前的Subject
        Subject subject  = SecurityUtils.getSubject();
        try {  
            //在调用了login方法后,SecurityManager会收到AuthenticationToken,并将其发送给已配置的Realm执行必须的认证检查  
            //每个Realm都能在必要时对提交的AuthenticationTokens作出反应  
            //所以这一步在调用login(token)方法时,它会走到MyRealm.doGetAuthenticationInfo()方法中,具体验证方式详见此方法  
            subject .login(token);
            logger.info("对用户[" + username + "]进行登录验证..验证通过");
            resultPageURL = "index";  
        }catch(UnknownAccountException uae){
            logger.info("对用户[" + username + "]进行登录验证..验证未通过,未知账户");
            message_login="未知账户";
        }catch(IncorrectCredentialsException ice){
            logger.info("对用户[" + username + "]进行登录验证..验证未通过,错误的凭证");
            message_login="密码不正确";
        }catch(LockedAccountException lae){
            logger.info("对用户[" + username + "]进行登录验证..验证未通过,账户已锁定");
            message_login="账户已锁定";
        }catch(ExcessiveAttemptsException eae){
            logger.info("对用户[" + username + "]进行登录验证..验证未通过,错误次数过多");
            message_login="用户名或密码错误次数过多";
        }catch(AuthenticationException ae){  
            //通过处理Shiro的运行时AuthenticationException就可以控制用户登录失败或密码错误时的情景  
            logger.info("对用户[" + username + "]进行登录验证..验证未通过,堆栈轨迹如下");
            ae.printStackTrace();
            message_login="用户名或密码不正确";
        }  
        //验证是否登录成功  
        if(subject .isAuthenticated()){
            logger.info("用户[" + username + "]登录认证通过(这里可以进行一些认证通过后的一些系统参数初始化操作)");
        }else{  
            token.clear();  
        }
        request.setAttribute("message_login", message_login);
        return resultPageURL;
    }  
    
    

    
   
}
